#pragma once

// include all the states
#include "IBaseObject.h"

// advanced data structures
#include <list>

class CDirect3D;
class CRetroInput;
class IBaseObject;
class CBaseObject;
class CCamera;
class CPlayerObject;
class CBaseEnemy;
class CProjectile;
enum EnemyType;
class CObjectManager
{
private: // singleton
	CObjectManager(void);
	~CObjectManager(void);
	CObjectManager(const CObjectManager*);
	CObjectManager& operator=(const CObjectManager*);

	static CObjectManager* m_pInstance;
public: // singleton
	static CObjectManager* GetInstance();
	static void FreeInstance();

private:
	CCamera* m_pCamera;

	std::list<IBaseObject*> m_ActiveObjectList;
	std::list<IBaseObject*> m_ObjectsToRemove;
	std::list<IBaseObject*> m_FreeObjectList;
	CPlayerObject* m_pPlayer;

	IBaseObject* FindFreeObjectByType(ObjectType type, int subType = 0);
	void FlushPendingObjects();
public: // functions

	// object related
	void Initialize(CCamera *pCamera);
	void Shutdown();
	void AddObject(IBaseObject* pObject);
	void RemoveObject(IBaseObject* pObject);
	void FlushObjects();

	// specific object creators
	inline CPlayerObject* GetPlayer() { return m_pPlayer;}
	CPlayerObject*	CreatePlayerObject(float posX, float posY);
	CBaseEnemy*		CreateEnemy(float posX, float posY, EnemyType enemyType);
	CProjectile*	CreateProjectile(float posX, float posY, float dirX, float dirY);
	// runtime related
	void Update(float fDeltaTime);
	void Input(CRetroInput* pInput);
	void Render(CDirect3D* pRender);

};

